﻿using System;
using System.Configuration;
using System.Collections.Generic;
using System.DirectoryServices;

using TempEmployees.BLL.UserAccess;

namespace TempEmployees.BLL.UserAccess.ActiveDirectory
{
    class ActiveDirectoryAccess : ILoginService
    {
        private static readonly string LDAP_CONNECTION_STRING = ConfigurationManager.ConnectionStrings["ActiveDirectoryConnectionString"].ConnectionString;

        public IUserDetails Logon(string username, string password)
        {
            Dictionary<string, List<string>> userDetails;
            if (!ActiveDirectoryAccess.CheckUserCredentials(username, password, out userDetails)) throw new Exception("שם משתמש או סיסמא שגוים");

            ActiveDirectoryResultsParser parser = new ActiveDirectoryResultsParser(userDetails);
            if (parser.ParseID() == string.Empty) throw new Exception("לא נמצא מספר הזהות של המשתמש");

            return ProccessActiveDirectoryUser(parser);
        }

        public static bool CheckUserCredentials(string username, string password, out Dictionary<string, List<string>> result)
        {
            result = new Dictionary<string, List<string>>();

            DirectoryEntry entry = new DirectoryEntry(LDAP_CONNECTION_STRING, username, password);
            if (entry == null) return false;

            DirectorySearcher search = new DirectorySearcher(entry);
            search.Filter = string.Format("(SAMAccountName={0})", username);
            //search.PropertiesToLoad.Add("memberOf");

            SearchResult searchResult = search.FindOne();
            if (searchResult != null)
                foreach (string property in searchResult.Properties.PropertyNames)
                    foreach (object value in searchResult.Properties[property])
                    {
                        if (!result.ContainsKey(property)) result.Add(property, new List<string>());
                        result[property].Add(value.ToString());
                    }
            return true;
        }

        private IUserDetails ProccessActiveDirectoryUser(ActiveDirectoryResultsParser parser)
        {
            IUserDetails details = UserDetailsGenerator.GenerateUserDetails(parser.ParseID());

            string first, last;
            parser.ParseName(out first, out last);
            details.SetFirstName(first);
            details.SetLastName(last);

            int departmentId = 0;
            int roles = parser.ParseRoles(ref departmentId);

            details.SetDepartmentID(departmentId);
            details.SetRoles(roles);

            return details;
        }
    }
}
